/*
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.3 $
 * * DATE
 * *    $Date: 2008/04/19 09:15:52 $
 * * LOG
 * *    $Log: LPCreator.java,v $
 * *    Revision 1.3  2008/04/19 09:15:52  animesh
 * *    multipath done
 * *
 * * */
package atag.compiler.powerassigner;

import java.io.PrintStream;

/**
 *
 * @author Animesh
 */
public class LPCreator {

    /** Creates a new instance of LPCreator */
    public LPCreator() {
    }

    /**
     * @deprecated
     * @returns string that contains the equivalent LP
     * @param m Number of tasks
     * @param n Number of nodes
     * @param T T_ik = cost of setting task i on node k
     * @param R R_ijk = cost at k for sending one data unit from i to j
     * @param f f_i = frequency of task i
     * @param s s_ij = amount of data transferred on (i,j) edge in DE
     * @param e0 e0_k = initial energy at node k
     */
    public static String returnLP(int m, int n, double[][] T,
            double[][][] R, double[] f,
            double[][] s, double[] e0) {
        String retstring = "";
        String vardecstring = "";


        retstring = "" +
                "/* Objective function */\n" +
                "min: c;\n" +
                "\n" +
                "/* Variable bounds */\n";
        for (int k = 0; k < n; k++) {
            retstring += "0"; //for the initial "+" sign
            for (int i = 0; i < m; i++) {
                retstring += "" +
                        " + " + f[i] * T[i][k] + " x" + "_" + i + "_" + k;
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    if (s[i][j] != 0) {
                        //if the edge (i,j) exists
                        for (int a = 0; a < n; a++) {
                            for (int b = 0; b < n; b++) {
                                retstring += "" +
                                        " + " +
                                        f[i] * s[i][j] * R[a][b][k] + " y" + "_" + i + "_" + a + "_" + j + "_" + b;
                            }
                        }
                    }
                }
            }

            retstring += " <= c;\n";

        }

        vardecstring += "" +
                "/*variable declaration*/\n" +
                "int ";
        for (int i = 0; i < m; i++) {
            for (int k = 0; k < n; k++) {
                vardecstring += "x" + "_" + i + "_" + k + ", ";
                retstring += "x" + "_" + i + "_" + k + " + ";
            }
            retstring += " 0 = 1;\n";
        }


        vardecstring += ";\n";

        retstring += "\n\n";
        vardecstring += "" +
                "int ";
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        for (int b = 0; b < n; b++) {
                            retstring += "" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + i + "_" + a + " <= 0;\n" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + j + "_" + b + " <= 0;\n" +
                                    "x" + "_" + i + "_" + a + " + x" + "_" + j + "_" + b + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 1;\n" +
                                    "\n";

                            vardecstring += "" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + ", ";
                        }
                    }
                }
            }
        }
        vardecstring += ";\n";

        return (retstring + vardecstring);
    }

    /**
     * @returns string that contains the equivalent LP, minimizing max cost
     * @param m Number of tasks
     * @param n Number of nodes
     * @param T T_ik = cost of setting task i on node k
     * @param R R_ijk = cost at k for sending one data unit from i to j
     * @param f f_i = frequency of task i
     * @param s s_ij = amount of data transferred on (i,j) edge in DE
     * @param e0 e0_k = initial energy at node k
     * @param infinity = numbers that should be taken as infinity
     */
    public static void printMinMaxCostLPtoStream(int m, int n, double[][] T,
            double[][][] R, double[] f,
            double[][] s, double[] e0,
            PrintStream out, double infinity) {
        //String retstring = "";
        //String vardecstring = "";


        out.print("" +
                "/* Objective function */\n" +
                "min: c;\n" +
                "\n" +
                "/* Variable bounds */\n");
        for (int k = 0; k < n; k++) {
            //out.print("0"); //for the initial "+" sign
            for (int i = 0; i < m; i++) {
                if (T[i][k] < infinity) {
                    out.print("" +
                            " + " + f[i] * T[i][k] + " x" + "_" + i + "_" + k);
                }
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    if (s[i][j] != 0) {
                        //if the edge (i,j) exists
                        for (int a = 0; a < n; a++) {
                            if (T[i][a] < infinity) {
                                for (int b = 0; b < n; b++) {
                                    if (T[j][b] < infinity) {
                                        out.print("" +
                                                " + " +
                                                f[i] * s[i][j] * R[a][b][k] + " y" + "_" + i + "_" + a + "_" + j + "_" + b);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            out.print(" <= c;\n");

        }

        for (int i = 0; i < m; i++) {
            for (int k = 0; k < n; k++) {
                out.print("+ x" + "_" + i + "_" + k + " ");
            }
            out.print(" = 1;\n");
        }


        out.print("/*declaring impossible assignments*/\n");

        for (int k = 0; k < n; k++) {
            for (int i = 0; i < m; i++) {
                if (T[i][k] >= infinity) {
                    out.print("" +
                            "x" + "_" + i + "_" + k + "= 0;\n");
                }
            }
        }


        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    out.print("" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + i + "_" + a + " <= 0;\n" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + j + "_" + b + " <= 0;\n" +
                                            "x" + "_" + i + "_" + a + " + x" + "_" + j + "_" + b + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 1;\n" +
                                            "\n");
                                }

                            }
                        }
                    }
                }
            }
        }

//////////////////////////////
        out.print("" +
                "/*variable declaration*/\n");

        for (int i = 0; i < m; i++) {
            out.print("int x_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k);
            }
            out.print(";\n");
        }

//        out.print(";\n");

        //new idea... use SOS
        out.print("sos\n");
        for (int i = 0; i < m; i++) {
            out.print("SOS1: x" + "_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k + " ");
            }
            out.print(" <= 1;\n");
        }




        out.print("" +
                "int ");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        for (int b = 0; b < n; b++) {
                            out.print("" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + ", ");
                        }
                    }
                }
            }
        }
        out.print(";\n");




    }

    /**
     * @returns string that contains the equivalent LP
     * @param m Number of tasks
     * @param n Number of nodes
     * @param T T_ik = cost of setting task i on node k
     * @param R R_ijk = cost at k for sending one data unit from i to j
     * @param f f_i = frequency of task i
     * @param s s_ij = amount of data transferred on (i,j) edge in DE
     * @param e0 e0_k = initial energy at node k
     * @param infinity = numbers that should be taken as infinity
     */
    public static void printMinTotalCostLPtoStream(int m, int n, double[][] T,
            double[][][] R, double[] f,
            double[][] s, double[] e0,
            PrintStream out, double infinity) {
        //String retstring = "";
        //String vardecstring = "";


        out.print("" +
                "/* Objective function */\n" +
                "min:");
        for (int k = 0; k < n; k++) {
            //out.print("0"); //for the initial "+" sign
            for (int i = 0; i < m; i++) {
                if (T[i][k] < infinity) {
                    out.print("" +
                            " + " + f[i] * T[i][k] + " x" + "_" + i + "_" + k);
                }
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    if (s[i][j] != 0) {
                        //if the edge (i,j) exists
                        for (int a = 0; a < n; a++) {
                            if (T[i][a] < infinity) {
                                for (int b = 0; b < n; b++) {
                                    if (T[j][b] < infinity) {
                                        out.print("" +
                                                " + " +
                                                f[i] * s[i][j] * R[a][b][k] + " y" + "_" + i + "_" + a + "_" + j + "_" + b);
                                    }
                                }
                            }
                        }
                    }
                }
            }

        }

        out.print(";\n");


        out.print("" +
                "\n" +
                "/* Variable bounds */\n");

        for (int i = 0; i < m; i++) {
            for (int k = 0; k < n; k++) {
                out.print("+ x" + "_" + i + "_" + k + " ");
            }
            out.print(" = 1;\n");
        }


        out.print("/*declaring impossible assignments*/\n");

        for (int k = 0; k < n; k++) {
            for (int i = 0; i < m; i++) {
                if (T[i][k] >= infinity) {
                    out.print("" +
                            "x" + "_" + i + "_" + k + "= 0;\n");
                }
            }
        }


        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    out.print("" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + i + "_" + a + " <= 0;\n" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + j + "_" + b + " <= 0;\n" +
                                            "x" + "_" + i + "_" + a + " + x" + "_" + j + "_" + b + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 1;\n" +
                                            "\n");
                                }

                            }
                        }
                    }
                }
            }
        }

//////////////////////////////
        out.print("" +
                "/*variable declaration*/\n");

        for (int i = 0; i < m; i++) {
            out.print("int x_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k);
            }
        }

        out.print(";\n");

        //new idea... use SOS
        out.print("sos\n");
        for (int i = 0; i < m; i++) {
            out.print("SOS1: x" + "_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k + " ");
            }
            out.print(" <= 1;\n");
        }




        out.print("" +
                "int ");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        for (int b = 0; b < n; b++) {
                            out.print("" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + ", ");
                        }
                    }
                }
            }
        }
        out.print(";\n");




    }

    /**
     * @returns string that contains the equivalent MinMax LP
     * @param m Number of tasks
     * @param n Number of nodes
     * @param numPaths Number of Paths
     * @param T T_ik = cost of setting task i on node k
     * @param MR MR_ijk\rho = cost at k for sending one data unit from i to j using path \rho
     * @param f f_i = frequency of task i
     * @param s s_ij = amount of data transferred on (i,j) edge in DE
     * @param e0 e0_k = initial energy at node k
     * @param infinity = numbers that should be taken as infinity
     */
    public static void printMultiPathMinMaxCostLPtoStream(int m, int n, int numPaths,
            double[][] T, double[][][][] MR, double[] f, double[][] s,
            double[] e0, PrintStream out, double infinity) {


        out.print("" +
                "/* Objective function */\n" +
                "min: c;\n" +
                "\n" +
                "/* Variable bounds */\n");
        for (int k = 0; k < n; k++) {
            //out.print("0"); //for the initial "+" sign
            for (int i = 0; i < m; i++) {
                if (T[i][k] < infinity) {
                    out.print("" +
                            " + " + f[i] * T[i][k] + " x" + "_" + i + "_" + k);
                }
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    if (s[i][j] != 0) {
                        //if the edge (i,j) exists
                        for (int a = 0; a < n; a++) {
                            if (T[i][a] < infinity) {
                                for (int b = 0; b < n; b++) {
                                    if (T[j][b] < infinity) {
                                        for (int z = 0; z < numPaths; z++) {
                                            if (MR[a][b][a][z] < GraphUtils.INFINITY) {
                                                out.print("" +
                                                        " + " +
                                                        f[i] * s[i][j] * MR[a][b][k][z] +
                                                        " q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            out.print(" <= c;\n");

        }

        for (int i = 0; i < m; i++) {
            for (int k = 0; k < n; k++) {
                out.print("+ x" + "_" + i + "_" + k + " ");
            }
            out.print(" = 1;\n");
        }

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int rho = 0; rho < numPaths; rho++) {
                        out.print("+ z" + "_" + i + "_" + j + "_" + rho + " ");
                    }
                    out.print(" = 1;\n");
                }
            }
        }

        out.print("/*declaring impossible assignments*/\n");

        for (int k = 0; k < n; k++) {
            for (int i = 0; i < m; i++) {
                if (T[i][k] >= infinity) {
                    out.print("" +
                            "x" + "_" + i + "_" + k + "= 0;\n");
                }
            }
        }

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    for (int z = 0; z < numPaths; z++) {
                                        if (MR[a][b][a][z] >= GraphUtils.INFINITY) {
                                            //infinity
                                            out.print("" +
                                                    "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " = 0;\n");

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    for (int z = 0; z < numPaths; z++) {
                                        out.print("" +
                                                "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 0;\n" +
                                                "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " - z" + "_" + i + "_" + j + "_" + z + " <= 0;\n" +
                                                "y" + "_" + i + "_" + a + "_" + j + "_" + b + "+ z" + "_" + i + "_" + j + "_" + z + " - q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " <= 1;\n" +
                                                "\n");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    out.print("" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + i + "_" + a + " <= 0;\n" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + j + "_" + b + " <= 0;\n" +
                                            "x" + "_" + i + "_" + a + " + x" + "_" + j + "_" + b + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 1;\n" +
                                            "\n");
                                }

                            }
                        }
                    }
                }
            }
        }

//////////////////////////////
        out.print("" +
                "/*variable declaration*/\n");

        for (int i = 0; i < m; i++) {
            out.print("int x_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k);
            }
            out.print(";\n");
        }

        out.print("\n");

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    out.print("int z_" + i + "_" + j + "_" + 0);
                    for (int rho = 1; rho < numPaths; rho++) {
                        out.print(", z" + "_" + i + "_" + j + "_" + rho);
                    }
                    out.print(";\n");
                }
            }
        }

        

        //new idea... use SOS
        out.print("sos\n");
        for (int i = 0; i < m; i++) {
            out.print("SOS1: x" + "_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k + " ");
            }
            out.print(" <= 1;\n");
        }


        out.print("\n");

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    out.print("SOS1: " + "z" + "_" + i + "_" + j + "_" + 0);
                    for (int rho = 1; rho < numPaths; rho++) {
                        out.print(", z" + "_" + i + "_" + j + "_" + rho);
                    }
                    out.print(" <= 1 ;\n");
                }
            }
        }


        out.print("" +
                "int ");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        for (int b = 0; b < n; b++) {
                            out.print("" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + ", ");
                        }
                    }
                }
            }
        }
        out.print(";\n");
    }

    /**
     * @returns string that contains the equivalent LP
     * @param m Number of tasks
     * @param n Number of nodes
     * @param numPaths Number of Paths
     * @param T T_ik = cost of setting task i on node k
     * @param MR MR_ijk\rho = cost at k for sending one data unit from i to j using path \rho
     * @param f f_i = frequency of task i
     * @param s s_ij = amount of data transferred on (i,j) edge in DE
     * @param e0 e0_k = initial energy at node k
     * @param infinity = numbers that should be taken as infinity
     */
    public static void printMultiPathMinTotalCostLPtoStream(int m, int n,
            int numPaths, double[][] T, double[][][][] MR,
            double[] f, double[][] s, double[] e0,
            PrintStream out, double infinity) {
        //String retstring = "";
        //String vardecstring = "";


        out.print("" +
                "/* Objective function */\n" +
                "min:");
        for (int k = 0; k < n; k++) {
            //out.print("0"); //for the initial "+" sign
            for (int i = 0; i < m; i++) {
                if (T[i][k] < infinity) {
                    out.print("" +
                            " + " + f[i] * T[i][k] + " x" + "_" + i + "_" + k);
                }
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    if (s[i][j] != 0) {
                        //if the edge (i,j) exists
                        for (int a = 0; a < n; a++) {
                            if (T[i][a] < infinity) {
                                for (int b = 0; b < n; b++) {
                                    if (T[j][b] < infinity) {
                                        for (int z = 0; z < numPaths; z++) {
                                            if (MR[a][b][a][z] < GraphUtils.INFINITY) {
                                                out.print("" +
                                                        " + " +
                                                        f[i] * s[i][j] * MR[a][b][k][z] +
                                                        " q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        out.print(";\n");


        out.print("" +
                "\n" +
                "/* Variable bounds */\n");

        for (int i = 0; i < m; i++) {
            for (int k = 0; k < n; k++) {
                out.print("+ x" + "_" + i + "_" + k + " ");
            }
            out.print(" = 1;\n");
        }

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int rho = 0; rho < numPaths; rho++) {
                        out.print("+ z" + "_" + i + "_" + j + "_" + rho + " ");
                    }
                    out.print(" = 1;\n");
                }
            }
        }



        out.print("/*declaring impossible assignments*/\n");

        for (int k = 0; k < n; k++) {
            for (int i = 0; i < m; i++) {
                if (T[i][k] >= infinity) {
                    out.print("" +
                            "x" + "_" + i + "_" + k + "= 0;\n");
                }
            }
        }

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    for (int z = 0; z < numPaths; z++) {
                                        if (MR[a][b][a][z] >= GraphUtils.INFINITY) {
                                            //infinity
                                            out.print("" +
                                                    "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " = 0;\n");

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    for (int z = 0; z < numPaths; z++) {
                                        out.print("" +
                                                "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 0;\n" +
                                                "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " - z" + "_" + i + "_" + j + "_" + z + " <= 0;\n" +
                                                "y" + "_" + i + "_" + a + "_" + j + "_" + b + "+ z" + "_" + i + "_" + j + "_" + z + " - q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + " <= 1;\n" +
                                                "\n");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }




        //printing for x-x combo
        out.print("\n\n");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    out.print("" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + i + "_" + a + " <= 0;\n" +
                                            "y" + "_" + i + "_" + a + "_" + j + "_" + b + " - x" + "_" + j + "_" + b + " <= 0;\n" +
                                            "x" + "_" + i + "_" + a + " + x" + "_" + j + "_" + b + " - y" + "_" + i + "_" + a + "_" + j + "_" + b + " <= 1;\n" +
                                            "\n");
                                }

                            }
                        }
                    }
                }
            }
        }

//////////////////////////////
        out.print("" +
                "/*variable declaration*/\n");

        for (int i = 0; i < m; i++) {
            out.print("int x_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k);
            }
            out.print(";\n");
        }

        out.print("\n");

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    out.print("int z_" + i + "_" + j + "_" + 0);
                    for (int rho = 1; rho < numPaths; rho++) {
                        out.print(", z" + "_" + i + "_" + j + "_" + rho);
                    }
                    out.print(";\n");
                }
            }
        }


        //new idea... use SOS
        out.print("sos\n");
        for (int i = 0; i < m; i++) {
            out.print("SOS1: x" + "_" + i + "_" + 0);
            for (int k = 1; k < n; k++) {
                out.print(", x" + "_" + i + "_" + k + " ");
            }
            out.print(" <= 1;\n");
        }

        out.print("\n");

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    out.print("SOS1: " + "z" + "_" + i + "_" + j + "_" + 0);
                    for (int rho = 1; rho < numPaths; rho++) {
                        out.print(", z" + "_" + i + "_" + j + "_" + rho);
                    }
                    out.print(" <= 1 ;\n");
                }
            }
        }



        out.print("" +
                "int ");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        for (int b = 0; b < n; b++) {
                            out.print("" +
                                    "y" + "_" + i + "_" + a + "_" + j + "_" + b + ", ");
                        }
                    }
                }
            }
        }
        out.print(";\n");

        out.print("\n");
        out.print("" +
                "int ");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] != 0) {
                    //if the edge (i,j) exists
                    for (int a = 0; a < n; a++) {
                        if (T[i][a] < infinity) {
                            for (int b = 0; b < n; b++) {
                                if (T[j][b] < infinity) {
                                    for (int z = 0; z < numPaths; z++) {
                                        out.print("" +
                                                "q" + "_" + i + "_" + a + "_" + j + "_" + b + "_" + i + "_" + j + "_" + z + ", ");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        out.print(";\n");

    }
}
